package com.zhihaihe.file.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhihaihe.file.advice.CommonException;
import com.zhihaihe.file.mapper.UserMapper;
import com.zhihaihe.file.pojo.Role;
import com.zhihaihe.file.pojo.UserBean;
import com.zhihaihe.file.service.IUserService;
import com.zhihaihe.file.util.*;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Random;
import java.util.regex.Pattern;

@Slf4j
@Service
public class UserServiceImpl  extends ServiceImpl<UserMapper, UserBean> implements IUserService {

    @Resource
    UserMapper userMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean registerUser(UserBean userBean) {
        //判断验证码
        String telephone = userBean.getTelephone();


        if (isUserNameExit(userBean)) {
            throw new CommonException("用户名已存在!",ResultCodeEnum.UNKNOWN_ERROR.getCode());
        }
        if (!isPhoneFormatRight(userBean.getTelephone())){
            throw new CommonException("手机号格式不正确!",ResultCodeEnum.UNKNOWN_ERROR.getCode());
        }
        if (isPhoneExit(userBean)) {
            throw new CommonException("手机号已存在!",ResultCodeEnum.UNKNOWN_ERROR.getCode());
        }

        String salt = getSaltValue();
        String newPassword = new SimpleHash("MD5", userBean.getPassword(), salt, 1024).toHex();

        userBean.setSalt(salt);

        userBean.setPassword(newPassword);
        userBean.setRegisterTime(DateUtil.getCurrentTime());
        boolean result = save(userBean);
        //默认创建角色直接为2
        userMapper.insertUserRole(userBean.getUserId(), 2L);
        if (result) {
            return true;
        } else {
            throw new CommonException("用户注册失败，请检查输入信息！",ResultCodeEnum.UNKNOWN_ERROR.getCode());
        }
    }

    @Override
    public UserBean selectUserByopenid(String openid) {
        LambdaQueryWrapper<UserBean> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserBean::getOpenId, openid);
        return userMapper.selectOne(lambdaQueryWrapper);
    }

    @Override
    public UserBean findUserInfoByTelephone(String telephone) {
        LambdaQueryWrapper<UserBean> queryWrapper=  new LambdaQueryWrapper<>();
        queryWrapper.eq(UserBean::getTelephone,telephone);
        return userMapper.selectOne(queryWrapper);
    }

    @Override
    public UserBean getUserBeanByToken(String token){
        Claims c = null;
        if (org.apache.commons.lang3.StringUtils.isEmpty(token)) {
            return null;
        }

        token = token.replace("Bearer ", "");
        try {
            c = JjwtUtil.parseJWT(token);
        } catch (Exception e) {
            log.error("解码异常:" + e);
            return null;
        }
        if (c == null) {
            log.info("解码为空");
            return null;
        }
        String subject = c.getSubject();
        log.debug("解析结果：" + subject);
        UserBean tokenUserBean = JSON.parseObject(subject, UserBean.class);

        UserBean saveUserBean = new UserBean();
        String tokenPassword = "";
        String savePassword = "";
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(tokenUserBean.getPassword())) {
            saveUserBean = findUserInfoByTelephone(tokenUserBean.getTelephone());
            if (saveUserBean == null) {
                return null;
            }
            tokenPassword = tokenUserBean.getPassword();
            savePassword = saveUserBean.getPassword();
        } else if (org.apache.commons.lang3.StringUtils.isNotEmpty(tokenUserBean.getQqPassword())) {
            saveUserBean = selectUserByopenid(tokenUserBean.getOpenId());
            if (saveUserBean == null) {
                return null;
            }
            tokenPassword = tokenUserBean.getQqPassword();
            savePassword = saveUserBean.getQqPassword();
        }
        if (org.apache.commons.lang3.StringUtils.isEmpty(tokenPassword) || StringUtils.isEmpty(savePassword)) {
            return null;
        }
        if (tokenPassword.equals(savePassword)) {

            return saveUserBean;
        } else {
            return null;
        }
    }

    @Override
    public List<String> getUserRole(Long userId) {
        return userMapper.getUserRole(userId);
    }

    /**
     * 检测用户名是否存在
     *
     * @param userBean
     */
    public Boolean isUserNameExit(UserBean userBean) {
        LambdaQueryWrapper<UserBean> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserBean::getUsername, userBean.getUsername());
        List<UserBean> list = userMapper.selectList(lambdaQueryWrapper);
        return !CollectionUtils.isEmpty(list);
    }


    /**
     * 检测手机号是否存在
     *
     * @param userBean
     * @return
     */
    public Boolean isPhoneExit(UserBean userBean) {

        LambdaQueryWrapper<UserBean> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserBean::getTelephone, userBean.getTelephone());
        List<UserBean> list = userMapper.selectList(lambdaQueryWrapper);
        if (list != null && !list.isEmpty()) {
            return true;
        } else {
            return false;
        }

    }

    /**
     * 检查手机格式是否正确
     * @param phone
     * @return
     */
    public Boolean isPhoneFormatRight(String phone){
        boolean isRight = Pattern.matches(RegexConstant.PASSWORD_REGEX, phone);
        return isRight;
    }

    /**
     * 获取一个随机颜值
     * @return 盐
     */
    public static String getSaltValue() {
        Random r = new Random();
        StringBuilder sb = new StringBuilder(16);
        sb.append(r.nextInt(99999999)).append(r.nextInt(99999999));
        int len = sb.length();
        if (len < 16) {
            for (int i = 0; i < 16 - len; i++) {
                sb.append("0");
            }
        }
        String salt = sb.toString();
        return salt;
    }

}
